From e39ba51523a912f4c63fe7a833cd360b4aa288fa Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 25 Jul 2005 21:19:14 +0000 Subject: [PATCH] - allows to optionally boot the system with a policy already being active at startup; this works by adding a module line into the grub configuration file and placing the binary policy generated by the policy tool into the boot directory; This assumes that a maximum of one module line is used for the initrd in the grub configuration file - Question: do users pass more than one module to the kernel? - enables the policy hypervisor call on x86/64 - some function prototypes moved to include files - moves the version number in the java tool up to the current version (a better way of doing this will be submitted soon) Signed-off-by: Stefan Berger Signed-off-by: Reiner Sailer --- docs/misc/shype4xen_readme.txt | 18 +++++ .../policyprocessor/XmlToBinInterface.java | 2 +- xen/acm/acm_core.c | 69 ++++++++++++++++++- xen/acm/acm_policy.c | 15 ++-- xen/arch/x86/setup.c | 18 +++-- xen/arch/x86/x86_64/entry.S | 1 + xen/common/policy_ops.c | 8 +-- xen/include/acm/acm_core.h | 3 + xen/include/acm/acm_hooks.h | 9 ++- 9 files changed, 121 insertions(+), 22 deletions(-) diff --git a/docs/misc/shype4xen_readme.txt b/docs/misc/shype4xen_readme.txt index 35a2b359f3..8c3e78788a 100644 --- a/docs/misc/shype4xen_readme.txt +++ b/docs/misc/shype4xen_readme.txt @@ -567,4 +567,22 @@ is that policy files/management should be portable and independent of the platfo Our policy interface enables managers to create a single binary policy file in a trusted environment and distributed it to multiple systems for enforcement. +5. Booting with a binary policy: +******************************** +The grub configuration file can be adapted to boot the hypervisor with an +already active policy. To do this, a binary policy file - this can be +the same file as used by the policy_tool - should be placed into the boot +partition. The following entry from the grub configuration file shows how +a binary policy can be added to the system during boot time. Note that the +binary policy must be of the same type that the hypervisor was compiled +for. The policy module line should also only be added as the last module +line if XEN was compiled with the access control module (ACM). + +title XEN0 3.0 Devel + kernel /xen.gz dom0_mem=400000 + module /vmlinuz-2.6.12-xen0 root=/dev/hda2 ro console=tty0 + module /initrd-2.6.12-xen0.img + module /xen_sample_policy.bin + + ====================end-of file======================================= diff --git a/tools/misc/policyprocessor/XmlToBinInterface.java b/tools/misc/policyprocessor/XmlToBinInterface.java index 0f8df1e208..9e11ca9d45 100644 --- a/tools/misc/policyprocessor/XmlToBinInterface.java +++ b/tools/misc/policyprocessor/XmlToBinInterface.java @@ -123,7 +123,7 @@ public interface XmlToBinInterface final short binaryBufferHeaderSz = (3 * u32Size + 4* u16Size); /* copied directlty from policy_ops.h */ - final int POLICY_INTERFACE_VERSION = 0xAAAA0002; + final int POLICY_INTERFACE_VERSION = 0xAAAA0003; /* copied directly from acm.h */ final int ACM_MAGIC = 0x0001debc; diff --git a/xen/acm/acm_core.c b/xen/acm/acm_core.c index 7d628808fe..0de147f3d3 100644 --- a/xen/acm/acm_core.c +++ b/xen/acm/acm_core.c @@ -6,6 +6,9 @@ * Author: * Reiner Sailer * + * Contributors: + * Stefan Berger + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2 of the @@ -25,6 +28,7 @@ #include #include #include +#include #include #include @@ -81,9 +85,68 @@ acm_init_binary_policy(void *primary, void *secondary) acm_bin_pol.secondary_binary_policy = secondary; } +static int +acm_setup(unsigned int *initrdidx, + const multiboot_info_t *mbi, + unsigned long initial_images_start) +{ + int i; + module_t *mod = (module_t *)__va(mbi->mods_addr); + int rc = ACM_OK; + + if (mbi->mods_count > 1) + *initrdidx = 1; + + /* + * Try all modules and see whichever could be the binary policy. + * Adjust the initrdidx if module[1] is the binary policy. + */ + for (i = mbi->mods_count-1; i >= 1; i--) { + struct acm_policy_buffer *pol; + char *_policy_start; + unsigned long _policy_len; +#if defined(__i386__) + _policy_start = (char *)(initial_images_start + (mod[i].mod_start-mod[0].mod_start)); +#elif defined(__x86_64__) + _policy_start = __va(initial_images_start + (mod[i].mod_start-mod[0].mod_start)); +#else +#error Architecture unsupported by sHype +#endif + _policy_len = mod[i].mod_end - mod[i].mod_start; + if (_policy_len < sizeof(struct acm_policy_buffer)) + continue; /* not a policy */ + + pol = (struct acm_policy_buffer *)_policy_start; + if (ntohl(pol->magic) == ACM_MAGIC) { + rc = acm_set_policy((void *)_policy_start, + (u16)_policy_len, + ACM_USE_SECURITY_POLICY, + 0); + if (rc == ACM_OK) { + printf("Policy len 0x%lx, start at %p.\n",_policy_len,_policy_start); + if (i == 1) { + if (mbi->mods_count > 2) { + *initrdidx = 2; + } else { + *initrdidx = 0; + } + } else { + *initrdidx = 1; + } + break; + } else { + printk("Invalid policy. %d.th module line.\n", i+1); + } + } /* end if a binary policy definition, i.e., (ntohl(pol->magic) == ACM_MAGIC ) */ + } + return rc; +} + int -acm_init(void) +acm_init(unsigned int *initrdidx, + const multiboot_info_t *mbi, + unsigned long initial_images_start) { int ret = -EINVAL; @@ -127,11 +190,13 @@ acm_init(void) if (ret != ACM_OK) return -EINVAL; + acm_setup(initrdidx, mbi, initial_images_start); printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code)); - return ACM_OK; + return ret; } + #endif int diff --git a/xen/acm/acm_policy.c b/xen/acm/acm_policy.c index 3e08130d43..1f0d1f88fa 100644 --- a/xen/acm/acm_policy.c +++ b/xen/acm/acm_policy.c @@ -33,7 +33,7 @@ #include int -acm_set_policy(void *buf, u16 buf_size, u16 policy) +acm_set_policy(void *buf, u16 buf_size, u16 policy, int isuserbuffer) { u8 *policy_buffer = NULL; struct acm_policy_buffer *pol; @@ -53,16 +53,21 @@ acm_set_policy(void *buf, u16 buf_size, u16 policy) /* 1. copy buffer from domain */ if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) goto error_free; - if (copy_from_user(policy_buffer, buf, buf_size)) { - printk("%s: Error copying!\n",__func__); - goto error_free; + if (isuserbuffer) { + if (copy_from_user(policy_buffer, buf, buf_size)) { + printk("%s: Error copying!\n",__func__); + goto error_free; + } + } else { + memcpy(policy_buffer, buf, buf_size); } /* 2. some sanity checking */ pol = (struct acm_policy_buffer *)policy_buffer; if ((ntohl(pol->magic) != ACM_MAGIC) || (ntohs(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) || - (ntohs(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) { + (ntohs(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code) || + (ntohl(pol->policyversion) != POLICY_INTERFACE_VERSION)) { printkd("%s: Wrong policy magics!\n", __func__); goto error_free; } diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 10c525c989..1ca0ed7154 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -245,6 +245,8 @@ void __init __start_xen(multiboot_info_t *mbi) module_t *mod = (module_t *)__va(mbi->mods_addr); unsigned long firsthole_start, nr_pages; unsigned long initial_images_start, initial_images_end; + unsigned long _initrd_start = 0, _initrd_len = 0; + unsigned int initrdidx = 1; struct e820entry e820_raw[E820MAX]; int i, e820_raw_nr = 0, bytes = 0; struct ns16550_defaults ns16550 = { @@ -411,7 +413,7 @@ void __init __start_xen(multiboot_info_t *mbi) shadow_mode_init(); /* initialize access control security module */ - acm_init(); + acm_init(&initrdidx, mbi, initial_images_start); /* Create initial domain 0. */ dom0 = do_createdomain(0, 0); @@ -450,6 +452,13 @@ void __init __start_xen(multiboot_info_t *mbi) } } + if ( (initrdidx > 0) && (initrdidx < mbi->mods_count) ) + { + _initrd_start = initial_images_start + + (mod[initrdidx].mod_start - mod[0].mod_start); + _initrd_len = mod[initrdidx].mod_end - mod[initrdidx].mod_start; + } + /* * We're going to setup domain0 using the module(s) that we stashed safely * above our heap. The second module, if present, is an initrd ramdisk. @@ -457,11 +466,8 @@ void __init __start_xen(multiboot_info_t *mbi) if ( construct_dom0(dom0, initial_images_start, mod[0].mod_end-mod[0].mod_start, - (mbi->mods_count == 1) ? 0 : - initial_images_start + - (mod[1].mod_start-mod[0].mod_start), - (mbi->mods_count == 1) ? 0 : - mod[mbi->mods_count-1].mod_end - mod[1].mod_start, + _initrd_start, + _initrd_len, cmdline) != 0) panic("Could not set up DOM0 guest OS\n"); diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index 2efec412e4..26e38b69c6 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -587,6 +587,7 @@ ENTRY(hypercall_table) .quad do_boot_vcpu .quad do_set_segment_base /* 25 */ .quad do_mmuext_op + .quad do_policy_op .rept NR_hypercalls-((.-hypercall_table)/4) .quad do_ni_hypercall .endr diff --git a/xen/common/policy_ops.c b/xen/common/policy_ops.c index 11e28d25bc..1e5cab1b2e 100644 --- a/xen/common/policy_ops.c +++ b/xen/common/policy_ops.c @@ -37,11 +37,6 @@ long do_policy_op(policy_op_t *u_policy_op) #else -/* function prototypes defined in acm/acm_policy.c */ -int acm_set_policy(void *buf, u16 buf_size, u16 policy); -int acm_get_policy(void *buf, u16 buf_size); -int acm_dump_statistics(void *buf, u16 buf_size); - typedef enum policyoperation { POLICY, /* access to policy interface (early drop) */ GETPOLICY, /* dump policy cache */ @@ -89,7 +84,8 @@ long do_policy_op(policy_op_t *u_policy_op) ret = acm_set_policy( op->u.setpolicy.pushcache, op->u.setpolicy.pushcache_size, - op->u.setpolicy.policy_type); + op->u.setpolicy.policy_type, + 1); if (ret == ACM_OK) ret = 0; else diff --git a/xen/include/acm/acm_core.h b/xen/include/acm/acm_core.h index 7f444f2a7b..c302d873ff 100644 --- a/xen/include/acm/acm_core.h +++ b/xen/include/acm/acm_core.h @@ -113,6 +113,9 @@ struct ste_ssid { /* protos */ int acm_init_domain_ssid(domid_t id, ssidref_t ssidref); int acm_free_domain_ssid(struct acm_ssid_domain *ssid); +int acm_set_policy(void *buf, u16 buf_size, u16 policy, int isuserbuffer); +int acm_get_policy(void *buf, u16 buf_size); +int acm_dump_statistics(void *buf, u16 buf_size); #endif diff --git a/xen/include/acm/acm_hooks.h b/xen/include/acm/acm_hooks.h index 2e0f9edb25..a97f601463 100644 --- a/xen/include/acm/acm_hooks.h +++ b/xen/include/acm/acm_hooks.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -136,7 +137,9 @@ static inline int acm_pre_grant_map_ref(domid_t id) { return 0; } static inline int acm_pre_grant_setup(domid_t id) { return 0; } -static inline int acm_init(void) +static inline int acm_init(unsigned int *initrdidx, + const multiboot_info_t *mbi, + unsigned long start) { return 0; } static inline void acm_post_domain0_create(domid_t domid) { return; } @@ -337,7 +340,9 @@ static inline void acm_post_domain0_create(domid_t domid) acm_post_domain_create(domid, ACM_DOM0_SSIDREF); } -extern int acm_init(void); +extern int acm_init(unsigned int *initrdidx, + const multiboot_info_t *mbi, + unsigned long start); #endif -- 2.30.2